package lib.streaming;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import dto.ObjectInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.junit.Test;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * @author kxd
 * @date 2019/1/14 16:29
 * description:
 */
public class GroupByMultiValue {

    @Test
    public void testGroup() {
        ObjectInfo objectInfo0 = new ObjectInfo();
        objectInfo0.setId(Long.valueOf(1));
        objectInfo0.setOrderNumber("01");
        objectInfo0.setContractCode("0101");
        objectInfo0.setRechargeAmount(new BigDecimal("10.0"));
        objectInfo0.setRechargeChannel("JD");
        objectInfo0.setTradeType("A");

        ObjectInfo objectInfo1 = new ObjectInfo();
        objectInfo1.setId(Long.valueOf(2));
        objectInfo1.setOrderNumber("02");
        objectInfo1.setContractCode("0101");
        objectInfo1.setRechargeAmount(new BigDecimal("20.0"));
        objectInfo1.setRechargeChannel("JDA");
        objectInfo1.setTradeType("B");

        ObjectInfo objectInfo2 = new ObjectInfo();
        objectInfo2.setId(Long.valueOf(3));
        objectInfo2.setOrderNumber("03");
        objectInfo2.setContractCode("0101");
        objectInfo2.setRechargeAmount(new BigDecimal("30.0"));
        objectInfo2.setRechargeChannel("JDA");
        objectInfo2.setTradeType("B");

        ObjectInfo objectInfo3 = new ObjectInfo();
        objectInfo3.setId(Long.valueOf(4));
        objectInfo3.setOrderNumber("04");
        objectInfo3.setContractCode("0102");
        objectInfo3.setRechargeAmount(new BigDecimal("40.0"));
        objectInfo3.setRechargeChannel("JDA");
        objectInfo3.setTradeType("A");

        ObjectInfo objectInfo4 = new ObjectInfo();
        objectInfo4.setId(Long.valueOf(5));
        objectInfo4.setOrderNumber("05");
        objectInfo4.setContractCode("0102");
        objectInfo4.setRechargeAmount(new BigDecimal("50.0"));
        objectInfo4.setRechargeChannel("JDA");
        objectInfo4.setTradeType("b");
        List<ObjectInfo> list = Lists.newArrayList();

        list.add(objectInfo4);
        list.add(objectInfo3);
        list.add(objectInfo2);
        list.add(objectInfo1);
        list.add(objectInfo0);

        List<ObjectInfo> resultLists = Lists.newArrayList();
        Joiner joiner = Joiner.on(',');
        List<ObjectInfo> listTmp;
        Map<String, Map<String, List<ObjectInfo>>> results = list.stream().collect(Collectors
                .groupingBy(ObjectInfo::getContractCode,
                        Collectors.groupingBy(ObjectInfo::getTradeType)));
        for (Map.Entry<String, Map<String, List<ObjectInfo>>> listEntry : results.entrySet()) {
            Map<String, List<ObjectInfo>> tmpResult = listEntry.getValue();
            //合并相关的order_number_arr,recharge_amount_arr,recharge_amount,recharge_channel_arr
            for (Map.Entry<String, List<ObjectInfo>> entry : tmpResult.entrySet()) {
                listTmp = entry.getValue();
                if (CollectionUtils.isNotEmpty(listTmp)) {
                    BigDecimal rechargeAmountTotal = listTmp.stream()
                            .map(ObjectInfo::getRechargeAmount)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    List<Long> ids = listTmp.stream()
                            .map(ObjectInfo::getId)
                            .collect(toList());
                    String orderNumberStr = joiner.join(listTmp.stream().map(ObjectInfo::getOrderNumber).collect(toList()));
                    String rechargeChannelStr = joiner.join(listTmp.stream().map(ObjectInfo::getRechargeChannel).collect(toList()));
                    String rechargeAmountStr = joiner.join(listTmp.stream().map(ObjectInfo::getRechargeChannelArr).collect(toList()));
                    String idArr = joiner.join(ids);

                    ObjectInfo result = listTmp.get(0);
                    result.setOrderNumberArr(orderNumberStr);
                    result.setRechargeAmountArr(rechargeAmountStr);
                    result.setRechargeChannelArr(rechargeChannelStr);
                    result.setRechargeAmount(rechargeAmountTotal);
                    result.setIdArr(idArr);
                    resultLists.add(result);
                }
            }
        }
    }
}
